/******************************************************************************
 * Copyright 2010 Duane Merrill
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * For more information, see our Google Code project site:
 * http://code.google.com/p/back40computing/
 *
 * Thanks!
 ******************************************************************************/

#pragma once

/******************************************************************************
 * Command-line parsing
 ******************************************************************************/
#include <map>
#include <algorithm>
#include <string>
#include <sstream>
class CommandLineArguments
{
protected:

    std::map<std::string, std::string> pairs;

public:

    // Constructor
    CommandLineArguments(int argc, char** argv)
    {
        using namespace std;

        for (int i = 1; i < argc; i++)
        {
            string arg = argv[i];

            if ((arg[0] != '-') || (arg[1] != '-'))
            {
                continue;
            }

            string::size_type pos;
            string key, val;

            if ((pos = arg.find('=')) == string::npos)
            {
                key = string(arg, 2, arg.length() - 2);
                val = "";
            }
            else
            {
                key = string(arg, 2, pos - 2);
                val = string(arg, pos + 1, arg.length() - 1);
            }

            pairs[key] = val;
        }
    }

    bool CheckCmdLineFlag(const char* arg_name)
    {
        using namespace std;
        map<string, string>::iterator itr;

        if ((itr = pairs.find(arg_name)) != pairs.end())
        {
            return true;
        }

        return false;
    }

    template <typename T>
    void GetCmdLineArgument(const char* arg_name, T& val);

    int ParsedArgc()
    {
        return pairs.size();
    }
};

template <typename T>
void CommandLineArguments::GetCmdLineArgument(const char* arg_name, T& val)
{
    using namespace std;
    map<string, string>::iterator itr;

    if ((itr = pairs.find(arg_name)) != pairs.end())
    {
        istringstream strstream(itr->second);
        strstream >> val;
    }
}

template <>
void CommandLineArguments::GetCmdLineArgument<char*>(const char* arg_name, char*& val)
{
    using namespace std;
    map<string, string>::iterator itr;

    if ((itr = pairs.find(arg_name)) != pairs.end())
    {

        string s = itr->second;
        val = (char*) malloc(sizeof(char) * (s.length() + 1));
        strcpy(val, s.c_str());

    }
    else
    {
        val = NULL;
    }
}

